package com.cx.service.impl;

import com.cx.dto.CustomerDto;
import com.cx.entity.Customer;
import com.cx.repository.CustomerRepository;
import com.cx.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.domain.Specifications;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springside.modules.utils.mapper.BeanMapper;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;


/**
 * 第三种方案
 * @Author: 舒建辉
 * @Description:
 * @Date: Created on 2018/2/2
 * @Version: 1.0
 */
@Service
public class CustomerServiceImpl implements CustomerService {

    @Autowired
    private CustomerRepository customerRepository;

    /**
     * @Author: 舒建辉
     * @Description:
     * @Date: Created on 2018/2/2
     * @Version: 1.0
     */
    @Override
    public Customer save(Customer customer) {
        return customerRepository.save(customer);
    }

    @Override
    public List<Customer> save(List<Customer> customers) {
        return customerRepository.save(customers);
    }

    @Override
    public List<Customer> findAll() {
        return customerRepository.findAll();
    }

    @Override
    public Customer findById(Long id) {
        return customerRepository.findOne(id);
    }

    @Override
    public List<Customer> findBySex(Integer sex) {
        return customerRepository.findBySex(sex);
    }

    @Override
    public List<Customer> findByName(String name) {
        return customerRepository.findByName(name);
    }

    @Override
    public List<Customer> findByNameOrSurname(String name, String surname) {
        return customerRepository.findByNameOrSurname(name, surname);
    }

    @Override
    public Integer delete(Long id) {
        customerRepository.delete(id);
        return 1;
    }

    @Override
    public CustomerDto findByCustomerId(Long id) {
        return customerRepository.findByCustomerId(id);
    }

    @Override
    public List<CustomerDto> findByTaskIds(List<Long> ids) {
        return customerRepository.findByTaskIds(ids);
    }

    @Override
    public List<Long> findByCustomerIds(List<Long> ids) {
        return customerRepository.findByCustomerIds(ids);
    }

    @Override
    public List<CustomerDto> findCustomerDtoByIds(List<Long> ids) {
        List<Customer> entities = customerRepository.findAll(ids);
        return BeanMapper.mapList(entities, Customer.class, CustomerDto.class);
    }

    @Override
    public Page<Customer> findPage(Integer page, Integer size) {
        PageRequest pageRequest =new  PageRequest(page-1,size);
        Page<Customer> entities = customerRepository.findAll(pageRequest);
        return entities;
    }

    @Override
    public Page<Customer> findPageSortById(Integer page, Integer size) {
        Sort sort = new Sort(Sort.Direction.DESC,"id");
        Pageable pageable = new PageRequest(page-1,size,sort);
        return customerRepository.findAll(pageable);
    }


    @Override
    public List<Customer> findBySortById() {
         Sort sort = new Sort(Sort.Direction.DESC,"id");
         return customerRepository.findAll(sort);
    }

    @Override
    public Page<Customer> findPageBySex(Integer page, Integer size,Integer sex) {

        Specification<Customer> specification = ((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            Predicate likeNickSex = criteriaBuilder.like(root.get("sex").as(String.class),sex+"%");
            predicates.add(likeNickSex);
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        });

        Pageable pageable = new PageRequest(page-1,size);
        return customerRepository.findAll(specification,pageable);
    }

    @Override
    public List<Customer> findBySpecBySex() {

        Specification<Customer> specification = ((root, criteriaQuery, criteriaBuilder) -> {
            root = criteriaQuery.from(Customer.class);
            Path<String> nameExp = root.get("id");
            return criteriaBuilder.like(nameExp,"2");
        });

        return customerRepository.findAll(specification);
    }

    @Override
    public List<Customer> findByCustomer() {
        Customer customer = new Customer();
        customer.setName("00w");
        customer.setEmail("221@cx.com");

        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith())
                .withIgnorePaths("focus");
        Example<Customer> ex = Example.of(customer,matcher);

        return  customerRepository.findAll(ex);
    }

    @Override
    public List<Customer> findByCustomerBySort() {
        Sort sort = new Sort(Sort.Direction.DESC,"id");

        Customer customer = new Customer();
        customer.setName("00w");
        customer.setEmail("221@cx.com");

        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith())
                .withIgnorePaths("focus");
        Example<Customer> ex = Example.of(customer,matcher);

        return customerRepository.findAll(ex,sort);
    }

    @Override
    public Page<Customer> findPageByCustomer() {
        Pageable pageable = new PageRequest(0,1);

        Customer customer = new Customer();
        customer.setName("00w");
        customer.setEmail("221@cx.com");

        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith())
                .withIgnorePaths("focus");
        Example<Customer> ex = Example.of(customer,matcher);
        return customerRepository.findAll(ex,pageable);
    }


}
